package top.cluski.feieprint.api.teable.entity;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
import top.cluski.feieprint.api.teable.TeableApi;
import top.cluski.feieprint.api.teable.domain.dto.PaotuiConfig;
import top.cluski.feieprint.api.teable.domain.dto.ShansongConfig;
import top.cluski.feieprint.api.youzan.YouzanApi;
import top.cluski.feieprint.api.youzan.entity.SpuRespEntity;
import top.cluski.feieprint.api.youzan.entity.TradeOrderRespEntity;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER;
import static top.cluski.feieprint.api.teable.entity.Filter.Conjunction.and;
import static top.cluski.feieprint.api.teable.entity.Filter.Operator.is;

@Data
public class RecordAddEntity {
    @JSONField(name = "日期")
    String date;
    @JSONField(name = "尺寸")
    String size;
    @JSONField(name = "夹心")
    List<String> sandwich;
    @JSONField(name = "款式")
    String style;
    @JSONField(name = "备注")
    String remark;
    @JSONField(name = "地址")
    String address;
    @JSONField(name = "联系电话")
    String mobile;
    @JSONField(name = "配送方式")
    String deliveryType = "";
    @JSONField(name = "送出时间")
    String postStartTime = "";
    @JSONField(name = "应收金额")
    Double price;
    @JSONField(name = "优惠金额")
    Double discountAmount;
    @JSONField(name = "账号")
    String account;
    @JSONField(name = "支付方式")
    String payType = "有赞";
    @JSONField(name = "有赞订单号")
    String orderId;
    @JSONField(name = "类型")
    String category;
    @JSONField(name = "下单日期")
    String openOrderDate;

    @JSONField(name = "生产店铺")
    String orderShop;
    @JSONField(name = "配送店铺")
    String sendShop;

    @JSONField(serialize = false)
    String picUrl;

    public static YouzanApi youzanApi;

    public static String DELIVERY_TYPE_ZIQU = "自取";
    public static String DELIVERY_TYPE_SHANSONG = "闪送汽车";
    public static String DELIVERY_TYPE_PAOTUI = "跑腿";

    public static List<RecordAddEntity> convert(TradeOrderRespEntity.FullOrderInfo orderDetail, TradeOrderRespEntity.Order order,
                                                boolean processPeijian) {
        // 小于100的判断一下是不是配件
        SpuRespEntity spu = youzanApi.getSpu(order.getSku_no());
        if (Double.parseDouble(order.getPrice()) < 100 && processPeijian) {
            if ("蛋糕配件".equals(spu.getCategory_name())) {
                JSONArray jsonArray = JSONArray.parse(order.getSku_properties_name());
                List<String> props = new ArrayList<>();
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    String val = jsonObject.getString("v");
                    props.add(val);
                }

                int propsSize = props.size();
                for (int i = 0; i < order.getNum() - 1; i++) {
                    for (int j = 0; j < propsSize; j++) {
                        props.add(props.get(j));
                    }
                }

                RecordAddEntity recordAddEntity = new RecordAddEntity();
                recordAddEntity.setStyle(order.getTitle());
                recordAddEntity.setRemark(String.join("+", props));
                return List.of(recordAddEntity);
            }
        }


        String size = getSize(order);

        Result result = getResult(orderDetail);

        RecordAddEntity recordAddEntity = new RecordAddEntity();
        recordAddEntity.setDate(result.date());
        recordAddEntity.setSize(size);
        recordAddEntity.setSandwich(getSandwich(order));
        recordAddEntity.setStyle(order.getTitle());
        recordAddEntity.setRemark(getRemark(orderDetail, order));
        recordAddEntity.setAddress(getAddress(result, orderDetail));
        recordAddEntity.setMobile(youzanApi.decrypt(orderDetail.getAddress_info().getReceiver_tel()));
        recordAddEntity.setDeliveryType(result.deliveryType());
        recordAddEntity.setPostStartTime(getPostStartTime(result.deliveryType(), orderDetail));
        recordAddEntity.setPrice(Double.parseDouble(order.getPrice()));
        recordAddEntity.setDiscountAmount(Double.parseDouble(order.getPrice()) - Double.parseDouble(order.getPayment()));
        recordAddEntity.setOrderId(orderDetail.getOrder_info().getTid());
        recordAddEntity.setPicUrl(RecordAddEntity.getPicUrl(order));
        recordAddEntity.setCategory(spu.getCategory_name());
        recordAddEntity.setOpenOrderDate(genOpenOrderDate());
        convertShop(orderDetail.getOrder_info(), recordAddEntity);
        convertAccount(orderDetail.getSource_info(), recordAddEntity);

        if ("蛋糕配件".equals(spu.getCategory_name()) || "P231019078725307".equals(order.getSku_barcode())) {
            return List.of(recordAddEntity);
        } else {
            // 对应一个order，多个数量
            int num = order.getNum();
            List<RecordAddEntity> recordAddEntities = new ArrayList<>();
            for (int i = 0; i < num; i++) {
                recordAddEntities.add(recordAddEntity);
            }
            return recordAddEntities;
        }
    }

    private static void convertAccount(TradeOrderRespEntity.SourceInfo sourceInfo, RecordAddEntity recordAddEntity) {
        String account = switch (sourceInfo.getSource().getPlatform()) {
            case "wx":
            case "browser":
            case "alipay":
                yield "有赞";
            case "other": {
                if (StrUtil.isBlank(sourceInfo.getOrder_mark())) {
                    yield "有赞-其他";
                }
                yield switch (sourceInfo.getOrder_mark()) {
                    case "wx_shop" -> "有赞";
                    case "xiaohongshu_mini_program" -> "有赞-小红书";
                    case "meituan" -> "有赞-美团";
                    default -> "有赞-其他";
                };
            }
            default:
                yield "有赞-其他";
        };

        recordAddEntity.setAccount(account);
    }

    private static String getPostStartTime(String deliveryType, TradeOrderRespEntity.FullOrderInfo orderDetail) {
        if (StrUtil.isNotBlank(orderDetail.getAddress_info().getSelf_fetch_info())) {
            // 自提
            String time = JSONUtil.parseObj(orderDetail.getAddress_info().getAddress_extra()).getStr("selfFetchAppointmentTime").split(",")[0];
            return LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(time)), ZoneId.systemDefault())
                    .format(DateTimeFormatter.ofPattern("HH:mm"));
        }
        LocalDateTime deliveryStartTime = LocalDateTime.parse(orderDetail.getAddress_info().getDelivery_start_time(), NORM_DATETIME_FORMATTER);

        int distance = (int) (5 + Double.parseDouble(orderDetail.getPay_info().getPost_fee()) / 3);
        if (DELIVERY_TYPE_PAOTUI.equals(deliveryType)) {
            PaotuiConfig paotuiConfig = PaotuiConfig.fromTeable();
            int minutes = paotuiConfig.getFirstPeriodMinutes() + (distance - 1) * paotuiConfig.getMinutesPerMile();
            return deliveryStartTime.minusMinutes(minutes).format(DateTimeFormatter.ofPattern("HH:mm"));
        } else if (DELIVERY_TYPE_SHANSONG.equals(deliveryType)) {
            ShansongConfig shansongConfig = ShansongConfig.fromTeable();
            int minutesPerMile = shansongConfig.getMinutesPerMile();
            for (LocalTime[] highTimePeriod : shansongConfig.getHighTimePeriods()) {
                if (deliveryStartTime.isAfter(LocalDateTime.of(deliveryStartTime.toLocalDate(), highTimePeriod[0]))
                        && deliveryStartTime.isBefore(LocalDateTime.of(deliveryStartTime.toLocalDate(), highTimePeriod[1]))) {
                    minutesPerMile = shansongConfig.getHighMinusPerMile();
                    break;
                }
            }
            int minutes = shansongConfig.getFirstPeriodMinutes() + (distance - 10) * minutesPerMile;
            return deliveryStartTime.minusMinutes(minutes).format(DateTimeFormatter.ofPattern("HH:mm"));
        } else {
            return "";
        }
    }

    private static String getRemark(TradeOrderRespEntity.FullOrderInfo orderDetail, TradeOrderRespEntity.Order order) {
        String remark = "";

        if (orderDetail.getRemark_info() != null && StrUtil.isNotBlank(orderDetail.getRemark_info().getBuyer_message())) {
            remark += orderDetail.getRemark_info().getBuyer_message();
        }

        if (orderDetail.getRemark_info() != null && StrUtil.isNotBlank(orderDetail.getRemark_info().getTrade_memo())) {
            remark += "\n" + orderDetail.getRemark_info().getTrade_memo();
        }

        if (StrUtil.isNotBlank(order.getBuyer_messages())
                && !"{}".equals(order.getBuyer_messages())
                && !"[]".equals(order.getBuyer_messages())
                && !"[\"\"]".equals(order.getBuyer_messages())) {
//            String tmp = JSONObject.parseObject(order.getBuyer_messages()).getString("备注");
//            if (StrUtil.isNotBlank(tmp)) {
//                remark += "\n" + remark;
//            }
            Map<String, String> stringStringMap = JSONObject.parseObject(order.getBuyer_messages(), new TypeReference<>() {
            });
            Map<String, String> collect = stringStringMap.entrySet().stream()
                    .filter(item -> StrUtil.isNotBlank(item.getValue()))
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
            if (!collect.isEmpty()) {
                String jsonString = JSONObject.toJSONString(collect);
                remark += "\n" + jsonString;
            }
        }

        // 目前是针对九宫格款式，增加了餐具的识别
        if (StrUtil.isNotBlank(order.getSku_properties_name())) {
            JSONArray skuProps = JSONArray.parse(order.getSku_properties_name());
            for (int i = 0; i < skuProps.size(); i++) {
                JSONObject skuProp = skuProps.getJSONObject(i);
                if (StrUtil.contains(skuProp.getString("k"), "餐具")) {
                    remark += "\n" + skuProp.getString("v");
                    break;
                }
            }
        }

        return remark;
    }


    private static List<String> getSandwich(TradeOrderRespEntity.Order order) {
        ArrayList<String> res = new ArrayList<>();
        // 优先识别 item_props 中的内容
        JSONArray jsonArray = JSONArray.parse(order.getItem_props());
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            if (StrUtil.isNotBlank(jsonObject.getString("value_name"))) {
                String valueName = jsonObject.getString("value_name");
                if (valueName.contains("+")) {
                    res.addAll(Arrays.stream(valueName.split("\\+")).toList());
                } else {
                    res.add(valueName);
                }
            }
        }

        if (res.isEmpty()) {
            JSONArray skuProps = JSONArray.parse(order.getSku_properties_name());
            for (int i = 0; i < skuProps.size(); i++) {
                JSONObject skuProp = skuProps.getJSONObject(i);
                if (StrUtil.contains(skuProp.getString("k"), "夹心")) {
                    res.addAll(Arrays.stream(skuProp.getString("v").split("\\+")).toList());
                }
            }
        }

        return res;
    }

    private static Result getResult(TradeOrderRespEntity.FullOrderInfo orderDetail) {
        String date;
        String deliveryType;
        if (StrUtil.isNotBlank(orderDetail.getAddress_info().getSelf_fetch_info())) {
            deliveryType = DELIVERY_TYPE_ZIQU;
            JSONObject selfFetchInfo = JSONObject.parse(youzanApi.decrypt(orderDetail.getAddress_info().getSelf_fetch_info()));
            String userTimeText = selfFetchInfo.getString("user_time").split(" ")[0];
            date = LocalDate.now().getYear() + "-" + userTimeText.substring(0, 2) + "-" + userTimeText.substring(3, 5);
        } else {
            LocalDateTime datetime = LocalDateTime.parse(orderDetail.getAddress_info().getDelivery_start_time(), NORM_DATETIME_FORMATTER);
            date = datetime.format(DatePattern.NORM_DATE_FORMATTER);

            if (Double.parseDouble(orderDetail.getPay_info().getPost_fee()) > 15) {
                deliveryType = DELIVERY_TYPE_SHANSONG;
            } else {
                deliveryType = DELIVERY_TYPE_PAOTUI;
            }
        }
        return new Result(date, deliveryType);
    }

    private record Result(String date, String deliveryType) {
    }

    private static String getSize(TradeOrderRespEntity.Order order) {
        String size = "";
        JSONArray skuPropNames = JSONArray.parse(order.getSku_properties_name());
        if (skuPropNames == null) return size;
        for (int i = 0; i < skuPropNames.size(); i++) {
            JSONObject skuProp = skuPropNames.getJSONObject(i);
            if ("尺寸".equals(skuProp.getString("k"))) {
                size = skuProp.getString("v")
                        .split("（")[0]
                        .split("\\(")[0]
                        .trim();
                break;
            } else if ("规格".equals(skuProp.getString("k"))) {
                size = skuProp.getString("v");
                break;
            }
        }
        return size;
    }

    private static String genOpenOrderDate() {
        LocalTime nowTime = LocalTime.now();
        // 21点之后订单，计入第二天
        if (nowTime.getHour() >= 21) {
            return LocalDate.now().plusDays(1).format(DatePattern.NORM_DATE_FORMATTER);
        } else {
            return LocalDate.now().format(DatePattern.NORM_DATE_FORMATTER);
        }
    }

    private static boolean isSelfFetch(String deliveryType) {
        return DELIVERY_TYPE_ZIQU.equals(deliveryType);
    }

    private static String getPicUrl(TradeOrderRespEntity.Order order) {
        TeableApi teableApi = SpringUtil.getBean(TeableApi.class);
        List<RecordEntity> records = teableApi.getRecords("tblkgu9Q62sBeKOsC7S", Filter.create()
                .setConjunction(and)
                .setFilterSet(Set.of(FilterItem.create()
                        .setFieldId("款式")
                        .setOperator(is)
                        .setValue(order.getTitle()))));
        if (records.isEmpty()) {
            return order.getPic_path();
        } else {
            JSONArray jsonArray = records.get(0).getFields().getJSONArray("额外图片");
            AttachmentInfo attachmentInfo = jsonArray.getObject(0, AttachmentInfo.class);
            return attachmentInfo.getPresignedUrl();
        }
    }

    private static String getAddress(Result result, TradeOrderRespEntity.FullOrderInfo orderDetail) {
        if (isSelfFetch(result.deliveryType())) {
            return "";
        } else {
            String deliveryProvince = orderDetail.getAddress_info().getDelivery_province();
            String deliveryCity = orderDetail.getAddress_info().getDelivery_city();
            String deliveryDistrict = orderDetail.getAddress_info().getDelivery_district();
            String tmp = youzanApi.decrypt(orderDetail.getAddress_info().getDelivery_address())
                    .replace("杭州市", "")
                    .replace("浙江省", "");
            if ("杭州市".equals(deliveryCity) && !tmp.contains(deliveryDistrict)) {
                // 如果在杭州市，并且没有区县，则加上区县
                tmp = deliveryDistrict + tmp;
            } else if (!"杭州市".equals(deliveryCity)) {
                // 不在杭州市的话，把省市区加上
                if (!tmp.contains(deliveryProvince)) tmp = deliveryProvince + tmp;
                if (!tmp.contains(deliveryCity)) tmp = deliveryCity + tmp;
                if (!tmp.contains(deliveryDistrict)) tmp = deliveryDistrict + tmp;
            }
            if (DELIVERY_TYPE_SHANSONG.equals(result.deliveryType())) {
                tmp = LocalDateTime.parse(orderDetail.getAddress_info().getDelivery_start_time(), NORM_DATETIME_FORMATTER).format(DateTimeFormatter.ofPattern("HH:mm"))
                        + "-"
                        + LocalDateTime.parse(orderDetail.getAddress_info().getDelivery_end_time(), NORM_DATETIME_FORMATTER).format(DateTimeFormatter.ofPattern("HH:mm"))
                        + "\n"
                        + tmp;
            }
            return tmp;
        }
    }

    private static void convertShop(TradeOrderRespEntity.OrderInfo orderInfo, RecordAddEntity recordAddEntity) {
        if (orderInfo.getShop_name().contains("下沙")) {
            recordAddEntity.setOrderShop("下沙店");
            recordAddEntity.setSendShop("下沙店");
        } else if (orderInfo.getShop_name().contains("上城")) {
            recordAddEntity.setOrderShop("上城店");
            recordAddEntity.setSendShop("上城店");
        }
    }
}
